<?php

namespace eolinker\command;

use eolinker\ApiDocGenerateTool;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\event\RouteLoaded;

class Eolinker extends Command
{
    protected function configure()
    {
        $this->setName('eolinker')
            ->addArgument('dir', Argument::OPTIONAL, '模块名称,默认data模块')
            ->addOption('action', 'a', Option::VALUE_OPTIONAL, 'action 过滤条件，默认不校验')
            ->addOption('url', 'u', Option::VALUE_OPTIONAL, 'path 过滤条件，默认不校验')
            ->addOption('method', 'm', Option::VALUE_OPTIONAL, 'method 过滤条件，默认不校验')
            ->addOption('content', 'c', Option::VALUE_OPTIONAL, '名称 过滤条件，默认不校验')
            ->setDescription('生成Eolinker文档');

// 命令示例
// php think eolinker data -a api.auth.Bank/detail -u api/bank -m get -c 获取银行卡详情

//        文档示例
//        /**
//         * @api            {get} api/home
//         * @apiName        获取轮播图片数据
//         * @apiStatus      working
//         * @apiDescription 获取轮播图片数据-描述
//         * @apiPermission  token
//         * @apiParam {integer} user_id=0 用户id
//         * @apiParam {object} data={car_base_price}
//         * @apiSuccess {object} data={car_base_price}
//         * @apiSuccess {integer} data.new_name 名称
//         */
    }

    protected function execute(Input $input, Output $output)
    {
        $dir = $input->getArgument('dir') ?: 'data';
        $path = $this->app->getRootPath() . "app/{$dir}/route/";

        $filters['uri'] = $input->getOption('url');
        $filters['action'] = $input->getOption('action');
        $filters['method'] = $input->getOption('method');
        $filters['name'] = $input->getOption('content');

        $routeList = $this->getRouteList($path);
        $this->generateDoc($routeList, $filters);
    }

    protected function getRouteList(string $path = null)
    {
        $this->app->route->setTestMode(true);
        $this->app->route->clear();

        $files = is_dir($path) ? scandir($path) : [];

        foreach ($files as $file) {
            if (strpos($file, '.php')) {
                include $path . $file;
            }
        }

        //触发路由载入完成事件
        $this->app->event->trigger(RouteLoaded::class);

        $routeList = $this->app->route->getRuleList();
        $rows = [];

        foreach ($routeList as $item) {
            $item['route'] = $item['route'] instanceof \Closure ? '<Closure>' : $item['route'];
            $item = [$item['rule'], $item['route'], $item['method'], $item['name'], $item['domain'], json_encode($item['option']), json_encode($item['pattern'])];
            $rows[] = $item;
        }

        return $rows;
    }

    protected function generateDoc($rows, $filters = [])
    {
        $wxaApiRepository = (new ApiDocGenerateTool())->init('admin', 4);
        $apiList = $wxaApiRepository->filterRoute($rows, $filters);
        $count = count($apiList);

        echo "一共匹配到了{$count}个路由" . PHP_EOL . PHP_EOL;

        foreach ($apiList as $api) {
            echo "开始生成 {$api['action']} - {$api['name']}" . PHP_EOL;
            $wxaApiRepository->createEoliknerDoc($api);
            echo "{$api['action']} - {$api['name']} 生成成功" . PHP_EOL. PHP_EOL;
        }

        echo "生成文档成功" . PHP_EOL;
    }
}
